﻿@page "/apis"
@layout ApiLayout
@using BootstrapBlazor.Components;
@using System.Collections.Generic;
@using System.Diagnostics.CodeAnalysis;
@using System.Linq;
@using System.Threading.Tasks;
@using System.Drawing
@inject HttpClient Http

 <Row ItemsPerRow="ItemsPerRow.One">
        <Card>
            <CardBody>
                 <Row ItemsPerRow="ItemsPerRow.Twelve">
                     <Row ColSpan="12">
                         <Select Items="Items" OnSelectedItemChanged="OnItemChanged" @bind-Value="value"></Select>
                    </Row>                                                  
                 </Row>
                  @if (parameterShow)
                  {
                      <h3 class="mt-3">参数设置</h3>
                      <div class="mt-3">                          
                           @foreach (var control in GetControls())
                           {
                              @switch (control.Type)
                              {
                                  case "TextEdit":
                                      <div class="mt-3">                                         
                                          <BootstrapInput TValue="string" IsAutoFocus="true" IsSelectAllTextOnFocus="true" 
                                           placeholder="@control.Label" 
                                           @bind-value="@DynamicDynamicValues[control.Label]"
                                           required="@control.IsRequired"
                                          />
                                      </div>
                                      break;
                              
                                  case "Checkbox":
                                        <div class="mt-3"> 
                                            <Row ItemsPerRow="ItemsPerRow.Twelve">
                                                <p>@control.Label</p>
                                                 @foreach (var item in control.ParamValue.Split(","))
                                                 {
                                                    var bindKeyValue = $"{control.ParamName}-{DynamicDynamicValues[item.ToString() + "Checkbox"]}";
                                              
                                                    <Checkbox TValue="string" DisplayText="@DynamicDynamicValues[item.ToString()+ "Checkbox"]" 
                                                        OnStateChanged="@OnStateChanged" 
                                                        @bind-Value="@bindKeyValue"
                                                        ShowAfterLabel="true" 
                                                        Size="BootstrapBlazor.Components.Size.Small"></Checkbox>                                             
                                                 } 
                                            </Row> 
                                </div>
                                break;
                                case "Select":
                                         var keyItems = GetParameterSelectItemsByLable(@control.Label);
                                         var itemValue = "";
                                         <div class="mt-3"> 
                                              <Row ItemsPerRow="ItemsPerRow.Twelve">
                                                    <Row ColSpan="12">
                                                         <Select Items="keyItems" OnSelectedItemChanged="OnParameterItemChanged" @bind-Value="itemValue"></Select>
                                                   </Row>                      
                                              </Row> 
                                         </div>
                                         parameterSelectItemValue = @control.Label;
                                break;
                              }
                           }
                      </div>
                   }
                   <div class="mt-3">
                         <Button IsBlock="true"  OnClick="@OnClick" Color="BootstrapBlazor.Components.Color.Primary" IsDisabled="@disabled" >发送请求</Button>
                   </div>
                  <div class="mt-3">
                          @if (textareaShow)
                          {
                               <Row ItemsPerRow="ItemsPerRow.Twelve">
                                  <Row ColSpan="12">
                                      <Textarea placeholder="返回结果 ..." rows="10" @bind-Value="@text"></Textarea>
                                  </Row>       
                               </Row>
                          }
                          @if (imageShow)
                          {
                               <CarouselImage ImageUrl="@text" />
                          }
                   </div>
            </CardBody>
        </Card>
    </Row>

@code{
    bool isFirst = true;
    bool parameterShow = false;
    bool disabled = false;
    bool textareaShow= false;
    bool imageShow= false;
    bool audioShow = false;
    string? value = "";
    string? url = "";
    string? text = "";
    string? parameterSelectItemValue="";
    private List<ControlDetails>? ControlList;
    private Dictionary<string, string>? DynamicDynamicValues = new Dictionary<string, string>();
    private Dictionary<string, string>? DynamicCheckboxValues = new Dictionary<string, string>();
    private List<ControlDetails>? Controls = new List<ControlDetails>();
    private IEnumerable<SelectedItem>? Items { get; set; }
    private List<ParameterSelectItem>? ParameterSelectItems { get; set; } = new List<ParameterSelectItem>();
    private List<Api>? ApiSelectItems = new List<Api>();


    protected override async Task OnInitializedAsync()
    {
        ApiSelectItems = await Http.GetFromJsonAsync<List<Api>>("/Api");

        List<SelectedItem> selectedItems = new List<SelectedItem>();
        foreach (var item in ApiSelectItems)
        {
            var selectedItem = new SelectedItem(item.Url, item.Title);
            selectedItems.Add(selectedItem);
        }
        Items = selectedItems;
    }

    private IEnumerable<SelectedItem>? EnumValueItems { get; set; }

    private Task OnItemChanged(SelectedItem item)
    {
        url = item.Value;
        parameterShow = ApiSelectItems?.Where(x => x.Url == url)?.FirstOrDefault()?.IsRequireParameter ?? false;
        if (parameterShow)
        {
            ControlList = GetControls();
            DynamicDynamicValues = ControlList?.ToDictionary(c => c.Label, c => "");
        }

        return Task.CompletedTask;
    }

    private Task OnParameterItemChanged(SelectedItem item)
    {
        ParameterSelectItems
        .Where(x => x.Key == parameterSelectItemValue)
        .FirstOrDefault().Items
        .Where(t => t.Active == true).FirstOrDefault().Active = false;

        ParameterSelectItems
        .Where(x => x.Key == parameterSelectItemValue)
        .FirstOrDefault().Items
        .Where(t => t.Value == item.Value).FirstOrDefault().Active = true;

        DynamicDynamicValues[parameterSelectItemValue] = item.Text;

        return Task.CompletedTask;
    }

    private async void OnClick(MouseEventArgs e)
    {
        string? parameter = "";
        var parameterDic = new Dictionary<string, object>();
        if (DynamicDynamicValues != null && DynamicDynamicValues.Count > 0)
        {
            foreach (var item in DynamicDynamicValues)
            {
                var control = ControlList?.Where(x => x.Label == item.Key)?.FirstOrDefault();
                var key = control?.ParamName ?? "";
                if (control?.Type == "Checkbox")
                {
                    var checkboxValue = DynamicCheckboxValues?[key];
                    parameterDic.Add(key,item.Value);
                }

                if (!parameterDic.ContainsKey(key) && control?.Type != "Checkbox")
                    parameterDic.Add(key,item.Value);
            }
            parameter = GetRequestParameter(parameterDic);
        }

        var api = ApiSelectItems?.Where(x => x.Url == url)?.FirstOrDefault();
        var result = new object();
        if (api?.RequestType == "POST")
        {
            result = await Http.PostAsJsonAsync<object>(url, parameterDic);//有问题的代码，需要处理
        }
        if (api?.RequestType?.ToUpper() == "GET")
        {
            if (api?.ReturnFormat?.ToUpper()=="JSON"||api?.ReturnFormat?.ToUpper()=="STRING")
            { 
                result = await Http.GetFromJsonAsync<object>(url + parameter);     
                text = result?.ToString();
                imageShow = false;
                textareaShow = true;
            }
            if (api?.ReturnFormat?.ToUpper()=="IMAGE")
            {
                var stream= await Http.GetStreamAsync(url + parameter);
                string ct64 = Convert.ToBase64String(ToByte(stream));
                text = $"data:image/png;base64,{ct64}";
                imageShow = true;
                textareaShow = false;
            }
            if (api?.ReturnFormat?.ToUpper() == "MP3")
            {
                var stream = await Http.GetStreamAsync(url + parameter);
            }
        }
    }

    private class ControlDetails
    {
        public string? Type { get; set; }
        public string? Label { get; set; }
        public string? ParamValue { get; set; }
        public string? ParamName { get; set; }
        public bool IsRequired { get; set; }
    }

    private List<ControlDetails> GetControls()
    {
        var result = new List<ControlDetails>();

        var api = ApiSelectItems?.Where(x => x.Url == url)?.FirstOrDefault();

        foreach (var requestParameters in api.RequestParameters)
        {
            var control = new ControlDetails
            {
                Type = requestParameters.ControlType,
                Label = requestParameters.Label,
                ParamValue = string.Join(",", requestParameters.EnumValue),
                ParamName = requestParameters.Name,
                IsRequired = true
            };

            if (control.Type == "Checkbox")
            {
                foreach (var item in requestParameters.EnumValue)
                {
                    if (!DynamicDynamicValues.ContainsKey(item.ToString() + "Checkbox"))
                        DynamicDynamicValues.Add(item.ToString() + "Checkbox", item.ToString());
                }
            }

            if (control.Type == "Select")
            {
                bool isExist = ParameterSelectItems?.Where(x => x.Key == requestParameters.Label)?.Any() ?? false;
                if (!isExist)
                {
                    ParameterSelectItem items = new ParameterSelectItem() ;
                    List<SelectedItem> selectedItems = new List<SelectedItem>();
                    bool isActive = true;
                    foreach (var item in requestParameters.EnumValue)
                    {

                        var selectedItem = new SelectedItem(item.ToString(), item.ToString());
                        selectedItem.Active = isActive;
                        selectedItems.Add(selectedItem);
                        isActive = false;
                    }
                    items.Key = requestParameters.Label;
                    items.Items = selectedItems;
                    ParameterSelectItems?.Add(items);
                }
            }

            result.Add(control);
        }

        return result;
    }

    private void ValueChanged(ChangeEventArgs a, string label)
    {
        DynamicDynamicValues[label] = a.Value.ToString();
    }


    private string GetValue(string label) 
    {
        return DynamicDynamicValues[label];
    }

    private string GetRequestParameter(Dictionary<string, object> dic)
    {
        string param = "?";
        foreach (var item in dic)
        {
            param += $"{item.Key}={item.Value}&";
        }

        return param.Substring(0, param.Length - 1);
    }

    private class Api
    {
        public string? Url { get; set; }
        public string? Title { get; set; }
        public string? RequestType  { get; set; }
        public string? ReturnFormat { get; set; }
        public bool IsRequireParameter { get; set; }
        public List<RequestParameter>? RequestParameters { get; set; } = new List<RequestParameter>();
    }

    private class RequestParameter
    {
        public string? Name { get; set; }
        public string? ParameterType { get; set; }
        public string? ControlType { get; set; }
        public List<object>? EnumValue 
        { 
            get 
            { 
                if (!string.IsNullOrWhiteSpace(Value))
                {
                    var data = new List<object>();
                    foreach (var item in Value.Split(",").ToList())
                    {
                        data.Add(item);
                    }
                    return data;
                }
                return new List<object>(); 
            }
        }
        public string? Value { get; set; }
        public string? Label { get; set; }
    }

    private class ParameterSelectItem
    {
        public string? Key { get; set; }
        public IEnumerable<SelectedItem>? Items { get; set; }
    }

    private IEnumerable<SelectedItem>? GetParameterSelectItemsByLable(string key)
    {
        return  ParameterSelectItems?.Where(x => x.Key == key)?.FirstOrDefault()?.Items;
    }

    private Task OnStateChanged(CheckboxState state, string value)
    {
        var values = value.Split("-");
        if (state == CheckboxState.Checked)
        {
            DynamicCheckboxValues?.Remove(values[0]);
            DynamicCheckboxValues[values[0]] = values[1];
        }
        else
        {
            DynamicCheckboxValues?.Remove(values[0]);
        }
        return Task.CompletedTask;
    }

    private byte[] ToByte(Stream stream)
    {
        byte[] bytes;
        using (var ms = new MemoryStream())
        {
            stream.CopyTo(ms);
            bytes = ms.ToArray();
        }
        return bytes;
    }
}